package com.cg.design.graphicdesignpattern.chainofresponsibility;

/**
 * 表示用来解决问题的抽象类，时职责链上的对象
 *
 * @program: LeetCode->Support
 * @description: 表示用来解决问题的抽象类，时职责链上的对象
 * @author: cg
 * @create: 2022-03-27 11:14
 **/
public abstract class Support {

    /**
     * 解决问题的实例的名字
     */
    private final String name;

    /**
     * 要推卸给的对象
     */
    private Support next;

    /**
     * 通过构造方法生成解决问题的实例
     *
     * @param name
     */
    public Support(String name) {
        this.name = name;
    }

    /**
     * 设置要推卸给的对象
     *
     * @param next
     * @return
     */
    public Support setNext(Support next) {
        this.next = next;
        return next;
    }

    /**
     * 解决问题的步骤
     *
     * @param trouble
     */
    public final void support(Trouble trouble) {
        // 递归
        if (resolve(trouble)) {
            done(trouble);
        } else if (next != null) {
            next.support(trouble);
        } else {
            fail(trouble);
        }
        Support support = this;
        while (true) {
            if (support.resolve(trouble)) {
                support.done(trouble);
                break;
            } else if (support.next == null) {
                support.fail(trouble);
                break;
            }
            support = support.next;
        }
    }

    @Override
    public String toString() {
        return "[" + name + "]";
    }

    /**
     * 解决问题的抽象方法
     *
     * @param trouble
     * @return
     */
    protected abstract boolean resolve(Trouble trouble);

    /**
     * 解决了问题调用方法
     *
     * @param trouble
     */
    protected void done(Trouble trouble) {
        System.out.println(trouble + " is resolved by " + this + ".");
    }

    /**
     * 为解决问题调用方法
     *
     * @param trouble
     */
    protected void fail(Trouble trouble) {
        System.out.println(trouble + " cannot be resolved.");
    }

}
